// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Jeff Stewart

#ifndef POPDIAG_UTIL_COMMON_H__
#define POPDIAG_UTIL_COMMON_H__

#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <QtCore/QString>

// common type definitions, etc.

namespace popdiag {

typedef enum { POP_PLAINTEXT_PORT = 110, POP_SSL_PORT = 995 } PopPorts;
typedef enum { IMAP_PLAINTEXT_PORT = 143, IMAP_SSL_PORT = 993 } ImapPorts;
typedef enum { SMTP_MX_PLAINTEXT_PORT = 25, SMTP_MSA_SSL_PORT = 465,
               SMTP_MSA_TLS_PORT = 587 } SmtpPorts;

QString IntToString(int i);

// returns true if the brand of the product should be Googlemail, rather than
// Gmail.
bool BrandIsGooglemailHere();

// place this as the last declaration in the private
// portion of your class definition to prevent object copying
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
  TypeName(const TypeName &); \
  void operator=(const TypeName&)


// We need to make sure that assert() statements are always
// generated. Otherwise, we lose the calls wrapped in them.
#undef NDEBUG
#include <assert.h>
#define CHECK(x) assert(x)
#define CHECK_EQ(x, y) assert((x) == (y))
#define CHECK_GT(x, y) assert((x) >  (y))
#define CHECK_GE(x, y) assert((x) >= (y))
#define CHECK_NE(x, y) assert((x) != (y))

//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
//  Copyright (c) 2001, 2002 Peter Dimov
//
//  Permission to copy, use, modify, sell and distribute this software
//  is granted provided this copyright notice appears in all copies.
//  This software is provided "as is" without express or implied
//  warranty, and with no claim as to its suitability for any purpose.
//
//  See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
template <typename T>
class scoped_ptr {
 private:

  T* ptr;

  // Note: This inclusion of a copy constructor is intentional.
  scoped_ptr(scoped_ptr const &);
  scoped_ptr & operator=(scoped_ptr const &);

 public:

  typedef T element_type;

  explicit scoped_ptr(T* p = 0): ptr(p) {}

  ~scoped_ptr() {
    typedef char type_must_be_complete[sizeof(T)];
    delete ptr;
  }

  void reset(T* p = 0) {
    typedef char type_must_be_complete[sizeof(T)];

    if (ptr != p) {
      delete ptr;
      ptr = p;
    }
  }

  T& operator*() const {
    assert(ptr != 0);
    return *ptr;
  }

  T* operator->() const  {
    assert(ptr != 0);
    return ptr;
  }

  bool operator==(T* p) const {
    return ptr == p;
  }

  bool operator!=(T* p) const {
    return ptr != p;
  }

  T* get() const  {
    return ptr;
  }

  void swap(scoped_ptr & b) {
    T* tmp = b.ptr;
    b.ptr = ptr;
       ptr = tmp;
  }

  T* release() {
    T* tmp = ptr;
    ptr = 0;
    return tmp;
  }

 private:

  // no reason to use these: each scoped_ptr should have its own object
  template <typename U> bool operator==(scoped_ptr<U> const& p) const;
  template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
};

template<typename T> inline
void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
  a.swap(b);
}

template<typename T> inline
bool operator==(T* p, const scoped_ptr<T>& b) {
  return p == b.get();
}

template<typename T> inline
bool operator!=(T* p, const scoped_ptr<T>& b) {
  return p != b.get();
}

}

#endif  // POPDIAG_UTIL_COMMON_H__
